package com.morningstar.flow.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.morningstar.flow.dao.entity.FlowInstanceTimeLine;
import com.morningstar.flow.dao.entity.FlowNode;
import com.morningstar.flow.dao.mapper.FlowInstanceTimeLineMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class FlowInstanceTimeLineService extends ServiceImpl<FlowInstanceTimeLineMapper, FlowInstanceTimeLine> {

    @Resource
    private FlowInstanceTimeLineMapper timeLineMapper;

    @Resource
    private FlowNodeService flowNodeService;

    public List<FlowInstanceTimeLine> getByProcessInstanceId(String processInstanceId) {
        LambdaQueryWrapper<FlowInstanceTimeLine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FlowInstanceTimeLine::getProcessInstanceId, processInstanceId);
        queryWrapper.orderByAsc(FlowInstanceTimeLine::getOperateTime);
        return timeLineMapper.selectList(queryWrapper);
    }

    /**
     * 发起流程
     */
    @Transactional(rollbackFor = Exception.class)
    public void processStart(String processInstanceId, Long userId, String processKey) {
        FlowNode flowNode = flowNodeService.getStartNodeByDefinitionKey(processKey);
        String startNodeActivityId = flowNode != null ? flowNode.getNodeActivityId() : "";
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(processInstanceId)
                .nodeActivityId(startNodeActivityId)
                .type("发起流程")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .build();
        timeLineMapper.insert(timeLine);
    }

    /**
     * 流程结束
     */
    @Transactional(rollbackFor = Exception.class)
    public void processEnd(String processInstanceId, String processDefinitionId) {
        FlowNode flowNode = flowNodeService.getEndNodeByDefinitionId(processDefinitionId);
        String endNodeActivityId = flowNode != null ? flowNode.getNodeActivityId() : "";
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(processInstanceId)
                .nodeActivityId(endNodeActivityId)
                .type("流程结束")
                .operateTime(LocalDateTime.now())
                .build();
        timeLineMapper.insert(timeLine);
    }

    /**
     * 撤销流程
     */
    @Transactional(rollbackFor = Exception.class)
    public void processRevocation(String processInstanceId, Long userId, String desc) {
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(processInstanceId)
                .type("撤销流程")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .description(desc)
                .build();
        timeLineMapper.insert(timeLine);
    }


    /**
     * 审批任务
     */
    @Transactional(rollbackFor = Exception.class)
    public void taskComplete(Task task, Long userId, Boolean audit, String desc) {
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(task.getProcessInstanceId())
                .nodeActivityId(task.getTaskDefinitionKey())
                .type(audit ? "审批通过" : "审批拒绝")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .description(desc)
                .build();
        timeLineMapper.insert(timeLine);
    }

    /**
     * 转交任务
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public void taskDeliver(Task task, Long userId, String desc) {
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(task.getProcessInstanceId())
                .nodeActivityId(task.getTaskDefinitionKey())
                .type("转交任务")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .description(desc)
                .build();
        timeLineMapper.insert(timeLine);
    }

    /**
     * 抄送节点
     */
    @Transactional(rollbackFor = Exception.class)
    public void taskCopy(ExecutionEntityImpl entity, Long userId, String desc) {
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(entity.getProcessInstanceId())
                .nodeActivityId(entity.getActivityId())
                .type("抄送")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .description(desc)
                .build();
        timeLineMapper.insert(timeLine);
    }

    /**
     * 驳回
     */
    @Transactional(rollbackFor = Exception.class)
    public void taskReject(ExecutionEntityImpl entity, Long userId, String desc) {
        FlowInstanceTimeLine timeLine = FlowInstanceTimeLine.builder()
                .processInstanceId(entity.getProcessInstanceId())
                .nodeActivityId(entity.getActivityId())
                .type("驳回")
                .userId(userId)
                .operateTime(LocalDateTime.now())
                .description(desc)
                .build();
        timeLineMapper.insert(timeLine);
    }
}
